import {
  IPSDEEditForm,
  IPSDEWizard,
  IPSDEWizardEditForm,
  IPSDEWizardForm,
  IPSDEWizardPanel,
  IPSDEWizardStep,
} from '@ibiz/dynamic-model-api';
import { AppCtrlControllerBase } from './app-ctrl-controller-base';
import { IMobStateWizardPanelController, IParam, IViewStateParam, MobWizardPanelEvents } from '../../../interface';
import { AppMobWizardPanelService } from '../../../ui-core/ctrl-service';
import { Subject } from 'rxjs';

export class MobStateWizardPanelController extends AppCtrlControllerBase implements IMobStateWizardPanelController {
  /**
   * @description 移动端状态向导面板实例对象
   * @type {IPSDEWizardPanel}
   * @memberof MobStateWizardPanelController
   */
  public controlInstance!: IPSDEWizardPanel;

  /**
   * @description 初始化行为
   * @private
   * @type {string}
   * @memberof MobStateWizardPanelController
   */
  private initAction: string = '';

  /**
   * @description 完成行为
   * @private
   * @type {string}
   * @memberof MobStateWizardPanelController
   */
  private finishAction: string = '';

  /**
   * @description 状态属性
   * @private
   * @type {string}
   * @memberof MobStateWizardPanelController
   */
  private stateField: string = '';

  /**
   * @description FormLoad是否被阻塞
   * @private
   * @type {boolean}
   * @memberof MobWizardPanelController
   */
  private hasFormLoadBlocked: boolean = false;

  /**
   * @description 首表单
   * @type {string}
   * @memberof MobStateWizardPanelController
   */
  public firstForm: string = '';

  /**
   * @description 步骤行为集合
   * @type {IParam}
   * @memberof MobStateWizardPanelController
   */
  public stepActions: IParam = {};

  /**
   * 步骤标识集合
   *
   * @type {IParam}
   * @memberof MobStateWizardPanelController
   */
  public stepTags: IParam = {};

  /**
   * @description 执行过的表单
   * @type {string[]}
   * @memberof MobStateWizardPanelController
   */
  public historyForms: string[] = [];

  /**
   * @description 当前激活步骤表单
   * @type {string}
   * @memberof MobStateWizardPanelController
   */
  public activeForm: string = '';

  /**
   * @description 向导表单集合
   * @type {any[]}
   * @memberof MobStateWizardPanelController
   */
  public wizardForms: any[] = [];

  /**
   * @description 向导表单参数
   * @type {IParam}
   * @memberof MobStateWizardPanelController
   */
  public formParam: IParam = {};

  /**
   * @description 当前状态
   * @private
   * @type {string}
   * @memberof MobStateWizardPanelController
   */
  private curState: string = '';

  /**
   * @description 向导步骤集合
   * @type {IParam[]}
   * @memberof MobStateWizardPanelController
   */
  public steps: IParam[] = [];

  /**
   * @description 视图状态订阅对象
   * @type {Subject<IViewStateParam>}
   * @memberof MobStateWizardPanelController
   */
  public wizardState: Subject<IViewStateParam> = new Subject();

  /**
   * @description 部件基础数据初始化
   * @memberof MobStateWizardPanelController
   */
  public ctrlBasicInit() {
    super.ctrlBasicInit();
    this.initAction = this.controlInstance.getInitPSControlAction()?.getPSAppDEMethod()?.codeName || 'Get';
    this.finishAction = this.controlInstance.getFinishPSControlAction()?.getPSAppDEMethod()?.codeName || 'Update';
    this.stateField = this.controlInstance.getStatePSAppDEField?.()?.codeName?.toLowerCase() || '';
    this.initFirstForm();
  }

  /**
   * @description 部件模型数据加载
   * @memberof MobStateWizardPanelController
   */
  public async ctrlModelLoad() {
    await super.ctrlModelLoad();
    if (!App.isPreviewMode()) {
      this.ctrlService = new AppMobWizardPanelService(this.controlInstance);
      await this.ctrlService.loaded();
    }
  }

  /**
   * @description 部件初始化
   * @param {*} [args]
   * @memberof MobStateWizardPanelController
   */
  public ctrlInit(args?: any) {
    super.ctrlInit(args);
    this.regFormActions();
    if (this.viewState) {
      this.viewStateEvent = this.viewState.subscribe(({ tag, action, data }: any) => {
        if (Object.is(tag, this.name)) {
          if (Object.is('load', action)) {
            this.doInit(data);
          }
        }
      });
    }
  }

  /**
   * @description 初始化首表单
   * @protected
   * @memberof MobStateWizardPanelController
   */
  protected initFirstForm() {
    const wizard: IPSDEWizard | null = this.controlInstance.getPSDEWizard();
    const wizardForms: Array<IPSDEWizardForm> = wizard?.getPSDEWizardForms() || [];
    if (wizard && wizardForms.length > 0) {
      const firstForm: IPSDEWizardForm = wizardForms.find((form: IPSDEWizardForm) => {
        return form.firstForm;
      }) as IPSDEWizardForm;
      if (App.isPreviewMode()) {
        this.activeForm = `${this.controlInstance.name}_form_${firstForm.formTag?.toLowerCase()}`;
      } else {
        this.firstForm = `${this.controlInstance.name}_form_${firstForm.formTag?.toLowerCase()}`;
      }
    }
  }

  /**
   * @description 注册表单步骤行为
   * @memberof MobStateWizardPanelController
   */
  public regFormActions() {
    const wizard: IPSDEWizard | null = this.controlInstance.getPSDEWizard();
    const wizardForms: Array<IPSDEWizardForm> = wizard?.getPSDEWizardForms() || [];
    const wizardSteps = wizard?.getPSDEWizardSteps?.() || [];
    if (wizard && wizardForms.length > 0) {
      wizardForms.forEach((stepForm: IPSDEWizardForm) => {
        const formName = `${this.controlInstance.name}_form_${stepForm.formTag?.toLowerCase()}`;
        const editForm: IPSDEWizardEditForm = (this.controlInstance.getPSDEEditForms() || []).find(
          (form: IPSDEEditForm) => {
            return form.name === formName;
          },
        ) as IPSDEWizardEditForm;
        const action = {
          loadAction: editForm?.getGetPSControlAction()?.actionName || 'Get',
          preAction: editForm?.getGoBackPSControlAction()?.actionName,
          nextAction: editForm?.getUpdatePSControlAction()?.actionName || 'Update',
          actions: stepForm.getStepActions() || [],
        };
        this.regFormAction(
          formName,
          action,
          this.getStepTag(wizardSteps, stepForm?.getPSDEWizardStep()?.stepTag as string),
        );
      });
    }
    if (wizardSteps.length > 0) {
      wizardSteps.forEach((step: IPSDEWizardStep) => {
        this.steps.push({
          tag: step.stepTag,
          title: step.title,
          subTitle: step.subTitle,
          className: step.getTitlePSSysCss?.()?.cssName,
          icon: step.getPSSysImage?.()?.cssClass,
        });
      });
    }
  }

  /**
   * @description 注册表单
   * @param {string} name 名称
   * @param {Array<string>} actions 步骤集合
   * @param {*} stepTag 步骤标识
   * @memberof MobStateWizardPanelController
   */
  public regFormAction(name: string, actions: IParam, stepTag: any) {
    this.stepActions[name] = actions;
    this.stepTags[name] = stepTag;
    this.wizardForms.push(name);
  }

  /**
   * @description 获取步骤标识
   * @param {Array<any>} wizardSteps 步骤数组
   * @param {string} tag 标识
   * @return {*}
   * @memberof MobStateWizardPanelController
   */
  public getStepTag(wizardSteps: Array<any>, tag: string) {
    if (wizardSteps && wizardSteps.length > 0 && tag) {
      let curStep: any = wizardSteps.find((step: any) => {
        return step.stepTag === tag;
      });
      return curStep.stepTag || tag;
    } else {
      return tag;
    }
  }

  /**
   * @description 初始化
   * @param {*} [opt={}] 额外参数
   * @memberof MobStateWizardPanelController
   */
  public doInit(opt: any = {}) {
    const arg: any = { ...opt };
    Object.assign(arg, { viewParam: this.viewParam });
    let tempContext: any = JSON.parse(JSON.stringify(this.context));
    this.onControlRequset('doInit', tempContext, arg);
    const post: Promise<any> = this.ctrlService.init(this.initAction, tempContext, arg, this.showBusyIndicator);
    post
      .then((response: any) => {
        this.onControlResponse('doInit', response);
        if (response && response.status === 200) {
          this.formParam = response.data;
          if (response.data[this.appDeCodeName.toLowerCase()]) {
            Object.assign(this.context, {
              [this.appDeCodeName.toLowerCase()]: response.data[this.appDeCodeName.toLowerCase()],
            });
          }
          this.computedActiveForm(this.formParam);
        }
      })
      .catch((response: any) => {
        this.onControlResponse('doInit', response);
        App.getNoticeService().error(response?.message);
      });
  }

  /**
   * @description 计算激活表单
   * @param {*} data
   * @memberof MobStateWizardPanelController
   */
  public computedActiveForm(data: any) {
    if (data[this.stateField]) {
      if (Object.keys(this.stepTags).length > 0) {
        Object.keys(this.stepTags).forEach((name: string) => {
          if (this.stepTags[name] === data[this.stateField]) {
            this.activeForm = name;
          }
        });
      }
      if (!this.activeForm) {
        this.activeForm = this.firstForm;
      }
    } else {
      this.activeForm = this.firstForm;
    }
    if (this.activeForm) {
      let index = this.wizardForms.indexOf(this.activeForm);
      this.wizardForms.forEach((item: any, inx: number) => {
        if (inx <= index) {
          this.historyForms.push(item);
        }
      });
    }
  }

  /**
   * @description 状态表单加载完成
   * @param {*} args 表单参数
   * @param {string} name 名称
   * @memberof MobStateWizardPanelController
   */
  public wizardPanelFormLoad(name: string, args: any) {
    if (args) {
      Object.assign(this.formParam, args);
    }
  }

  /**
   * @description 向导表单保存完成
   * @param {*} args 表单参数
   * @param {string} name 名称
   * @memberof MobStateWizardPanelController
   */
  public wizardPanelFormSave(name: string, args: any) {
    Object.assign(this.formParam, args);
    if (Object.is(this.curState, 'NEXT')) {
      this.historyForms.push(name);
      if (!this.stateField) {
        if (this.getNextForm()) {
          this.activeForm = this.getNextForm();
          setTimeout(() => {
            this.formLoad(this.formParam);
          }, 1);
        } else {
          this.doFinish();
        }
      } else {
        setTimeout(() => {
          this.formLoad(this.formParam);
        }, 1);
      }
    } else if (Object.is(this.curState, 'PREV')) {
      if (this.stateField) {
        setTimeout(() => {
          this.formLoad(this.formParam);
        }, 1);
      }
    } else if (Object.is(this.curState, 'FINISH')) {
      this.doFinish();
    }
  }

  /**
   * @description 获取下一步向导表单
   * @return {*}
   * @memberof MobStateWizardPanelController
   */
  public getNextForm() {
    let index = this.wizardForms.indexOf(this.activeForm);
    if (index >= 0) {
      if (this.wizardForms[index + 1]) {
        return this.wizardForms[index + 1];
      }
    }
    return undefined;
  }

  /**
   * @description 处理上一步
   * @memberof MobStateWizardPanelController
   */
  public handlePrevious() {
    if (!this.stateField) {
      const length = this.historyForms.length;
      if (length > 1) {
        this.curState = 'PREV';
        this.activeForm = this.historyForms[length - 1];
        setTimeout(() => {
          this.formLoad(this.formParam);
        }, 1);
        this.historyForms.splice(length - 1, 1);
      }
    } else {
      if (this.activeForm) {
        this.wizardState.next({
          tag: this.activeForm,
          action: 'panelAction',
          data: {
            action: this.stepActions[this.activeForm].preAction,
            emitAction: MobWizardPanelEvents.SAVE_SUCCESS,
            data: this.formParam,
          },
        });
      }
    }
  }

  /**
   * @description 处理下一步
   * @memberof MobStateWizardPanelController
   */
  public handleNext() {
    if (this.activeForm) {
      const form = this.ctrlRefsMap.get(this.activeForm);
      if (form && form.formValidateStatus && form.formValidateStatus instanceof Function) {
        form
          .formValidateStatus()
          .then((state: boolean) => {
            if (state) {
              this.curState = 'NEXT';
              this.wizardState.next({
                tag: this.activeForm,
                action: 'panelAction',
                data: {
                  action: this.stepActions[this.activeForm].nextAction,
                  emitAction: MobWizardPanelEvents.SAVE_SUCCESS,
                  data: this.formParam,
                },
              });
            } else {
              App.getNoticeService().error('值规则校验异常');
            }
          })
          .catch((error: any) => {
            App.getNoticeService().error(error);
          });
      }
    }
  }

  /**
   * @description 处理完成步骤
   * @memberof MobStateWizardPanelController
   */
  public handleFinish() {
    if (this.activeForm) {
      const form = this.ctrlRefsMap.get(this.activeForm);
      if (form && form.formValidateStatus && form.formValidateStatus instanceof Function) {
        form
          .formValidateStatus()
          .then((state: boolean) => {
            if (state) {
              this.curState = 'FINISH';
              this.wizardState.next({
                tag: this.activeForm,
                action: 'panelAction',
                data: {
                  action: this.stepActions[this.activeForm].saveAction,
                  emitAction: MobWizardPanelEvents.SAVE_SUCCESS,
                  data: this.formParam,
                },
              });
            } else {
              App.getNoticeService().error('值规则校验异常');
            }
          })
          .catch((error: any) => {
            App.getNoticeService().error(error);
          });
      }
    }
  }

  /**
   * @description 执行完成
   * @memberof MobStateWizardPanelController
   */
  public doFinish() {
    let arg: any = {};
    Object.assign(arg, this.formParam);
    Object.assign(arg, { viewparams: this.viewParam });
    let tempContext: any = JSON.parse(JSON.stringify(this.context));
    this.onControlRequset('doFinish', tempContext, arg);
    const post: Promise<any> = this.ctrlService.finish(this.finishAction, tempContext, arg, this.showBusyIndicator);
    post
      .then((response: any) => {
        this.onControlResponse('doFinish', response);
        if (response && response.status === 200) {
          const data = response.data;
          this.ctrlEvent('finish', data);
        }
      })
      .catch((response: any) => {
        this.onControlResponse('doFinish', response);
        App.getNoticeService().error(response?.message);
      });
  }

  /**
   * @description 表单加载
   * @param {string} name 表单名称
   * @memberof MobStateWizardPanelController
   */
  public formLoad(data: any) {
    if (this.stateField) this.computedActiveForm(data);
    if (this.activeForm) {
      this.wizardState.next({
        tag: this.activeForm,
        action: 'panelAction',
        data: {
          action: this.stepActions[this.activeForm].loadAction,
          emitAction: MobWizardPanelEvents.LOAD_SUCCESS,
          data: this.formParam,
        },
      });
    }
  }

  /**
   * @description 处理部件事件
   * @param {string} controlname 部件名称
   * @param {string} action 行为
   * @param {*} data 数据
   * @memberof MobStateWizardPanelController
   */
  public handleCtrlEvent(controlname: string, action: string, data: any) {
    switch (action) {
      case MobWizardPanelEvents.MOUNTED:
        this.setIsMounted(controlname, data);
        if (this.hasFormLoadBlocked) {
          this.formLoad(Object.assign(this.formParam, data));
          this.hasFormLoadBlocked = false;
        }
        break;
      case MobWizardPanelEvents.SAVE_SUCCESS:
        this.wizardPanelFormSave(controlname, data);
        break;
      case MobWizardPanelEvents.LOAD_SUCCESS:
        this.wizardPanelFormLoad(controlname, data);
        break;
      default:
        super.handleCtrlEvent(controlname, action, data);
    }
  }
}
